package com.zrc.japktool.apk.zipalignsign;

import com.zrc.japktool.util.TaskLog;
import pxb.android.zipalign.AxmlFastZipOut;
import pxb.android.zipalign.FastZipEntry;
import pxb.android.zipalign.FastZipIn;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import java.util.regex.Pattern;

public class Apk4kAligner {
    private TaskLog log = null;

    public Apk4kAligner(TaskLog log) {
        this.log = log;
    }

    public void zipAlign(String inputApkPath, String outputApkPath, boolean deleteSignature) throws Exception {
        log.tip("apk对齐: 开始 " + inputApkPath);
        log.tip("apk对齐: inputApkPath: " + inputApkPath);

        File inputApkFile = new File(inputApkPath);
        File outputApkFile = new File(outputApkPath);

        // 确保输出目录存在
        Path parent = outputApkFile.getParentFile().toPath();
        if (parent != null) {
            Files.createDirectories(parent);
        }

        FastZipIn in = null;
        AxmlFastZipOut out = null;

        try {
            in = new FastZipIn(inputApkFile);
            ByteBuffer manifest = null;

            // 查找并读取 AndroidManifest.xml
            for (FastZipEntry entry : in.entries()) {
                if (entry.utf8Name().equals("AndroidManifest.xml")) {
                    manifest = in.getUncompressed(entry);
                    break;
                }
            }

            out = new AxmlFastZipOut(outputApkFile);
            if (manifest != null) {
                out.initByAndroidManifestContent(manifest);
            }

            List<FastZipEntry> entries = in.entries();
            List<FastZipEntry> zipEntryList = cleanup(entries, deleteSignature);
            out.copy(in, zipEntryList);

            log.tip("输出文件: " + outputApkPath);
            log.tip("apk对齐: 结束");

        } catch (Exception e) {
            // 如果出现异常，尝试删除可能已经创建的不完整输出文件
            if (outputApkFile.exists()) {
                try {
                    Files.delete(outputApkFile.toPath());
                    log.tip("删除不完整的输出文件: " + outputApkPath);
                } catch (Exception deleteEx) {
                    log.tip("删除不完整输出文件失败: " + deleteEx.getMessage());
                }
            }
            throw e; // 重新抛出异常
        } finally {
            // 确保资源被关闭
            closeQuietly(out);
            closeQuietly(in);
        }
    }

    /**
     * 安静地关闭 FastZipIn 资源
     */
    private void closeQuietly(FastZipIn in) {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) {
                log.tip("关闭 FastZipIn 资源时出错: " + e.getMessage());
            }
        }
    }

    /**
     * 安静地关闭 AxmlFastZipOut 资源
     */
    private void closeQuietly(AxmlFastZipOut out) {
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) {
                log.tip("关闭 AxmlFastZipOut 资源时出错: " + e.getMessage());
            }
        }
    }

    public List<FastZipEntry> cleanup(List<FastZipEntry> entries, boolean deleteSignature) {
        List<FastZipEntry> zipEntryList = new ArrayList<>();
        for (FastZipEntry e : entries) {
            String name = e.utf8Name();
            if (name.endsWith("/")) {
                continue;
            }
            if (deleteSignature) {
                if (name.equals(JarFile.MANIFEST_NAME) ||
                        Pattern.compile("^META-INF/(.*)[.](SF|RSA|DSA|EC)$").matcher(name).matches()) {
                    continue;
                }
            }
            zipEntryList.add(e);
        }
        return zipEntryList;
    }
}